﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace LibUpdate
{
    /// <summary>
    /// XML升级文件解读
    /// </summary>
    public class UpdateVerXML
    {
        private static Colophon _Colophon;


        #region 解析服务器xml版本数据
        /// <summary>
        /// 开始解析XML文件内容，
        /// </summary>
        /// <returns>返回一个版本集合</returns>
        internal static Colophon BeginServerReder(string UpdateXMLPath)
        {

            _Colophon = new Colophon();
            try
            {
               
                XmlDocument doc = new XmlDocument();
                if (System.IO.File.Exists(UpdateXMLPath))
                {
                    doc.Load(UpdateXMLPath);

                    XmlNode node = doc.SelectSingleNode("colophon");
                    for (int i = 0; i < node.ChildNodes.Count; i++)
                    {
                        XmlNode xmlver = node.ChildNodes[i];
                        Version ver = XMLtoVersion(xmlver);
                        _Colophon.Add(ver);
                    }
                }

                return _Colophon;
            }
            catch(Exception e)
            {
                throw new Exception(e.Message);
            }
        }

        /// <summary>
        /// 解析本地版本描述文件信息
        /// </summary>
        /// <param name="UpdateXMLPath">xml文件地址</param>
        /// <returns></returns>
        public static Version XMLtoVersion(string UpdateXMLPath)
        {
            Version ver = new Version(); 
            XmlDocument doc = new XmlDocument();
            if (System.IO.File.Exists(UpdateXMLPath))
            {
                doc.Load(UpdateXMLPath);


                XmlNode node = doc.DocumentElement.SelectSingleNode("version");
                ver = XMLtoVersion(node);
            }
            return ver;
        }

        /// <summary>
        /// 获得子版本信息
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        private static Version XMLtoVersion(XmlNode node)
        {
            Version ver = new Version();
            foreach(XmlAttribute attr in node.Attributes)
            {
                switch (attr.Name.ToUpper())
                { 
                    //版本号s
                    case "VER":
                        System.Version _newver = new System.Version(attr.Value);
                        ver.VersionNum = _newver;

                        break;
                    //当前版本发布日期
                    case "RELEASEDATE":
                        ver.ReleaseDate = DateTime.Parse(attr.Value);
                        break;
                    //当前版本升级日志
                    case "REMARK":
                        ver.Remark = attr.Value;
                        break;
                    //当前版本所在相对目录
                    case "DIRECTORY":
                        ver.Directory = attr.Value;
                        break;            
                    //更新对象
                    case "UPDATEGOAL":
                        if (UpdateGoal.MainPro.ToString().ToUpper()==attr.Value.ToUpper())
                        {
                            ver.UpdateGoal = UpdateGoal.MainPro;
                        }
                        else if (UpdateGoal.MDB.ToString().ToUpper() == attr.Value.ToUpper())
                        {
                            ver.UpdateGoal = UpdateGoal.MDB;
                        }
                        if (UpdateGoal.UpdatePro.ToString().ToUpper() == attr.Value.ToUpper())
                        {
                            ver.UpdateGoal = UpdateGoal.UpdatePro;
                        }
                        break;                    
                    //是否需要重新启动计算机
                    case "REPEAT":
                        if (LJType.Yes .ToString().ToUpper() == attr.Value.ToUpper())
                        {
                            ver.Repeat = LJType.Yes;
                        }
                        else
                        {
                            ver.Repeat = LJType.No;
                        }
                        break;
                }
            }
            ver.FileList = XMLtoFileList(node);
            return ver;
        }


        /// <summary>
        /// 解析本地版本描述文件信息
        /// </summary>
        /// <param name="UpdateXMLPath">xml文件地址</param>
        /// <returns></returns>
        public static string XMLtoBase(string UpdateXMLPath) {
            XmlDocument doc = new XmlDocument();
            string addr = string.Empty;
            if (System.IO.File.Exists(UpdateXMLPath)) {
                doc.Load(UpdateXMLPath);


                XmlNode node = doc.DocumentElement.SelectSingleNode("updateset");
                addr = node.Attributes["addr"].Value;
            }
            return addr;
        }


        /// <summary>
        /// 获得文件列表信息
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        private static FileList XMLtoFileList(XmlNode node)
        {
            FileList filelist = new FileList();
            //读取文件数据列表
            for (int i = 0; i < node.ChildNodes.Count; i++)
            {
                XmlNode xmlver = node.ChildNodes[i];
                File file = new File();
                
                //将数据转换为file
                foreach (XmlAttribute at in xmlver.Attributes)
                {
                    if ("NAME" == at.Name.ToUpper())
                    {
                        file.FileName = at.Value;
                    }
                    else if ("PATH" == at.Name.ToUpper())
                    {
                        file.Path = at.Value;
                    }
                    else if ("SIZE" == at.Name.ToUpper())
                    {
                        file.Size = int.Parse(at.Value);
                    }
                    else if ("MD5" == at.Name.ToUpper())
                    {
                        file.MD5 = at.Value;
                    }
                    else if ("ACTIONTYPE" == at.Name.ToUpper())
                    {
                        #region 动作类型
                        if ("ADD" == at.Value.ToUpper())
                        {
                            file.ActionType = ActionType.Add;
                        }
                        else if ("EDIT" == at.Value.ToUpper())
                        {
                            file.ActionType = ActionType.Edit;
                        }
                        else if ("UPDATE" == at.Value.ToUpper())
                        {
                            file.ActionType = ActionType.Update;
                        }
                        else if ("DELETE" == at.Value.ToUpper())
                        {
                            file.ActionType = ActionType.Delete;
                        }
                        else if ("EXEC" == at.Value.ToUpper())
                        {
                            file.ActionType = ActionType.ExeC;
                        }
                        else
                        {
                            file.ActionType = ActionType.Update;
                        }
                        #endregion

                    }
                    else if ("TYPE" == at.Name.ToUpper())
                    {
                        #region 文件类型判断
                        if ("EXE" == at.Value.ToUpper())
                        {
                            file.Type = FileType.EXE;
                        }
                        else if ("DLL" == at.Value.ToUpper())
                        {
                            file.Type = FileType.DLL;
                        }
                        else if ("SHP" == at.Value.ToUpper())
                        {
                            file.Type = FileType.SHP;
                        }
                        else if ("IMAGE" == at.Value.ToUpper())
                        {
                            file.Type = FileType.Image;
                        }
                        else if ("DIRECTORY" == at.Value.ToUpper())
                        {
                            file.Type = FileType.Directory;
                        }
                        else if ("XML" == at.Value.ToUpper())
                        {
                            file.Type = FileType.XML;
                        }
                        else
                        {
                            file.Type = FileType.EXE;
                        }
                
                        #endregion

                    }
                }

                filelist.Add(file);
            }
            return filelist;
        }

        #endregion

        /// <summary>
        /// 设置客户端xml数据
        /// </summary>
        internal static bool SetVersionXml(string UpdateXMLPath, Version ver,string ServerPath) {
            try {

                XmlTextWriter xmlOut = new XmlTextWriter(UpdateXMLPath, System.Text.Encoding.UTF8);

                xmlOut.Formatting = Formatting.Indented;
                xmlOut.WriteStartDocument();

                xmlOut.WriteComment("当前版本");

                xmlOut.WriteStartElement("setting");
                xmlOut.WriteStartElement("updateset");
                xmlOut.WriteAttributeString("addr", ServerPath);
                xmlOut.WriteEndElement();

                xmlOut.WriteStartElement("version");
                xmlOut.WriteAttributeString("ver", ver.VersionNum.ToString());
                xmlOut.WriteAttributeString("Directory", ver.Directory);
                xmlOut.WriteAttributeString("ReleaseDate", ver.ReleaseDate.ToString());
                xmlOut.WriteAttributeString("UpdateGoal", ver.UpdateGoal.ToString());
                xmlOut.WriteAttributeString("Repeat", ver.Repeat.ToString());
                xmlOut.WriteAttributeString("Remark", ver.Remark);

                //文件列表
                for (int i = 0; i < ver.FileList.Count; i++) {
                    xmlOut.WriteStartElement("file");

                    xmlOut.WriteAttributeString("name", ver.FileList[i].FileName);
                    xmlOut.WriteAttributeString("path", ver.FileList[i].Path);
                    xmlOut.WriteAttributeString("size", ver.FileList[i].Size.ToString());
                    xmlOut.WriteAttributeString("md5", ver.FileList[i].MD5);

                    xmlOut.WriteAttributeString("actiontype", ver.FileList[i].ActionType.ToString());
                    xmlOut.WriteAttributeString("actionstate", ver.FileList[i].FileName);
                    xmlOut.WriteAttributeString("filetype", ver.FileList[i].Type.ToString());

                    xmlOut.WriteEndElement();
                }

                xmlOut.WriteEndElement();
                xmlOut.WriteEndElement();


                xmlOut.Flush();
                xmlOut.Close();

                return true;
            }
            catch {
                return false;
            }
        }
    }

}
